<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>
    // 原型对象  Cat.prototype  显式原型
    // 原型属性    __propo__    隐式原型


    // constructor  :原型对象的构造器属性


    //问题2. 公用的属性和方法重复声明  需要占据多余内存
    //  解决办法：把所有实例化对象 公有属性和方法提取出来 放到一个公共的位置(原型对象) => 允许所有的实例化对象


    // 所有的实例化对象在创建之初都设置了一个原型属性__proto__,引用了原型对象(Cat.prototype)
    // this.__propo__ = Cat.prototype;

    function Cat(name, color) {
        // this -> {}  指向函数在调用过程中创建的实例化对象
        // 将相关属性和方法  绑定到实例化对象上

        this.name = name;
        this.color = color;
        // this.species = "猫"
        // this.call = function(){
        //     console.log("猫猫");
        // },
        // this.skill = function(){
        //     console.log("捉老鼠");
        // }
    }
    Cat.prototype.species = "猫猫";
    Cat.prototype.call = function () {
        console.log("猫猫", this.species);
    };
    Cat.prototype.skill = function () {
        console.log("捉老鼠");
    };
    Cat.prototype.say = function () {
        console.log(this.color, this.name);
    };
    console.dir(Cat);   // 打印所有对象/函数的相关属性/方法(Cat.prototype)

    var Tom = new Cat("Tom", "pink");
    console.log(Tom);


    // 访问流程     先找实例自身，自己没有则通过原型属性__propo__查找构造函数的原型对象(Cat.prototype)

    console.log(Tom.color);     // 先找实例自身
    console.log(Tom.species);   // 没有则找原型对象
    console.log(Tom.call);


    // 此处this指向 构造函数的原型对象 Tom.__proto__  ->  Cat.prototype
    Tom.__proto__.say();    // this ->  Cat.prototype
    console.log(Tom.__proto__ === Cat.prototype);  // true

    // 所以一般要求省略__proto__
    Tom.say();              // this ->  Tom




    // constructor  :原型对象(prototype) 中自带的一个属性(构造器属性)

    // 1. 由构造函数自己默认给原型对象设置constructor      => 指向函数本身
    // 2.当实例化对象访问此属性时  =>  指向函数本身   =>  可知 该实例是由哪个构造函数创建
    console.log(Cat.prototype.constructor);     // Cat
    console.log(Cat.prototype.constructor === Cat);     // true
    console.log(Tom.constructor);
    console.log(Tom.constructor === Cat);   // true  // Tom是由构造函数Cat创建


</script>

</html>